// Treasure-Maps Copyright 2009, Thea Ganoe. This program is distributed under the terms of the GNU General Public License

     //<![CDATA[

	var gmarkers=[];
	var index = 0;
	var GLLstring = '';
	var tmpString = '';
	var position = 0;
	var imageURL = "test";
	var heading = "0";
	var description = "";
	var selectedPic = 0;
        var map;  //used by google


function GPXdata() {
	var GPXexists = false;
	var GPXdisplayed = false;
}

function createXMLHttpRequest() {
      try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0") }catch(e){}
      try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0") }catch(e){}

      try{ return new ActiveXObject("Msxml2.XMLHTTP") }catch(e){}

      try{ return new ActiveXObject("Microsoft.XMLHTTP") }catch(e){}
      try{ return new XMLHttpRequest(); } catch(e) {}

      throw new Error("Could not find an XMLHttpRequest alternative.")
	return null;
}
	
 function finishRoute() {
	tmpString = document.getElementById('infobox').value;
	tmpString = tmpString + '\n ]\n	};';
	document.getElementById('infobox').value = tmpString;
 }

function myObj2string() {
        //this function writes the current object as it is in memory to the json box
	var newString =JSON.stringify(myObj);
	document.getElementById('JSONbox').value = newString;
}

function placeMarker(llat, llon) {
	var marker = new GMarker(new GPoint(llon, llat));
  	map.addOverlay(marker);
	gmarkers[0] = marker ;

}

function picSelect(txt) {
	//selectedPic is a global variable that is updated here
	selectedPic = txt;
	sz = document.forms.length;
	for (i = 0; i < sz; i++) {
		tsz = 'd'+ (i.toString());
		document.getElementById(tsz).style.backgroundColor = "grey";
	}

	document.getElementById('d'+txt).style.backgroundColor = "white";

}//end picSelect

function showRoute(){
	//draw the polylines on the map
	//clears all existing overlays.  does not set a marker
        //will display encoded polylines if the myGPX object contains data
	var latitude, longitude, olatitude, olongitude;
	olatitude  = myObj.way[0].latitude;
	olongitude = myObj.way[0].longitude ;
	//alert("in showroute , lat and lon are: "+ olatitude, + ', ' + olongitude );
	map.clearOverlays();
	
	//draw a gpx map if there is one:
	if ( GPXdata.GPXexists == true ) {

		var encodedPolyline = new GPolyline.fromEncoded({
    			color: "#FF0000",
    			weight: 3,
    			points: myGPX.encoded_points,
    			levels: myGPX.encoded_levels,
    			zoomFactor: 32,
    			numLevels: 4
		});
		map.addOverlay(encodedPolyline);
		//alert("printed gpx on map");
        	//now show the gpx button
		document.getElementById('gpxData').style.visibility = "visible";
	} // else  {
	  //this for loop draws the picture lines:
	  for (i = 1; i < myObj.way.length; i++) {
		latitude = myObj.way[i].latitude;
        	longitude = myObj.way[i].longitude ;

		if ((longitude == NaN ) || (longitude == 0.0 ))  {
			//this can happen if an image has no geopoint recorded for it
			longitude = olongitude;
		}
		if ((latitude == NaN ) || (latitude == 0.0 ))  {
			latitude = olatitude;
		}
	
		if ( olatitude != latitude ) {
	 		var polyline = new GPolyline([
  		 	 	new GLatLng( olatitude, olongitude),
  		 	 	new GLatLng(latitude, longitude)
				], "#0000ff", 4);
			map.addOverlay(polyline);
		}
		olatitude = latitude;
		olongitude = longitude;
	  }
	//} //end else
} //end showRoute()

function mapLoader(llat, llon, lzoom) {
      // Create the map and place it.
      // map.setMapType(G_SATELLITE_TYPE);
	map = new GMap2(document.getElementById("map"));
	map.addControl(new GLargeMapControl());
        map.addControl(new GOverviewMapControl());
        map.setCenter(new GLatLng(llat, llon), lzoom);
	//for version 2, the zoom is = 17 - oldZoom
 	map.setMapType(G_HYBRID_MAP); 

	
     function createMarker(point) {	  }

     function gotoClick(longitude, latitude ) {
        	 // fill in the longitude and latitude fields for the picture selected
		//selectedPic is a global variable
		//update the myObj object
		//call showroute() to redraw the lines to reach the new point
	  	// Have our Google Map recenter or pan to the new location
	var intZoom = 15;
	if ( globalNode > 1 ) 	{
		intZoom = myObj.way[globalNode -1 ].zoom;
	}
        map.panTo(new GLatLng(latitude, longitude)); 
	switch (globalNode) {
	// if globalNode is 0 or higher it means a node is being edited
	//in the case of a new route being created, routeNew.html sets globalNode to -1
	// if a parking spot is being added, globalnode is -2
		case (-1 ) :
			document.getElementById('id_latitude').value = latitude;
			document.getElementById('id_longitude').value = longitude;
			document.getElementById('id_zoom').value = intZoom;
			break;
       		case (  -2 ) :
			document.getElementById('parkinglat').value = latitude;
			document.getElementById('parkinglon').value = longitude;
			break;
		case ( -3 ) :
			document.getElementById('restroomslat').value = latitude;
			document.getElementById('restroomslon').value = longitude;
			break;			
		default:
			var x = document.getElementById(globalNode + '_nodeform');
			x.elements['latitude'].value = latitude;
			x.elements['longitude'].value = longitude;
			x.elements['zoom'].value = intZoom;
			//now update the memory object 
			wayUpdate(globalNode, 'latitude', latitude );
			wayUpdate(globalNode, 'longitude', longitude );
			wayUpdate(globalNode, 'zoom', intZoom);
			showRoute();
			placeMarker(latitude, longitude);
			readyEditorButtons();
  			break;
	} //end switch
	//check to see if the save button has already been added:
	//if it is already false, no reason to add another identical button.
	if (saved == true) {

		saved = false;
		//show the save button so the edits can be saved
		//read the btnHolder string and add the new button at the end:
		var bstring = btns.strbtnSave
		var eb = document.getElementById('btnHolder').innerHTML;
		eb = eb + bstring;
		document.getElementById('btnHolder').innerHTML = eb;
	}

      } // end gotoClick

	GEvent.addListener(map, 'click', 
		function(overlay, point) {
		    if (point) {
			longitude = point.x;
			latitude = point.y;
			gotoClick(longitude, latitude );
		    } // end if point
		}  //end function overlay
	    );   // end of GEvent.addListener--notice this is a close parens
} //end mapLoader()
  

function recalibrate() {
	// adjust fractional or duplicate position values of the memory object to integer array indexes, this recalculates the position value to equal the index, adjusted for 1-based index since actual array starts with 0 , but our javascript dom object's node positions start with 1 (position 0_nodeform is reserved for the route). This should only be done when the display is updated too, so saveWay() calls it.  If drag and drop functionality were available for reorering the nodes, this function could be eliminated.
	for  ( i = 0; i < myObj.way.length ; i++ ) {
		//alert("recalibrating position is: "+ myObj.way[i].position  + " = i: " + i);
		 myObj.way[i].position = i ; 
	}
} //end recalibrate

function makeCover(nodeNum) {
		//user has selected a picList item to be the cover position and image
  		tempLat = myObj.way[nodeNum].latitude;
  		tempLon = myObj.way[nodeNum].longitude;
  		tempImg = myObj.way[nodeNum].img;
		tempgetPic = tempImg + "?imgmax=512";

		var x=document.getElementById("0_nodeform")
  		x.elements['latitude'].value = tempLat;
  		x.elements['longitude'].value = tempLon;
  		x.elements['image'].value = tempImg;
		var y = document.getElementById( "0_nodeImg");
		y.src = tempgetPic;
		//now update the object
		myObj.way[0 ].latitude = tempLat;
		myObj.way[0 ].longitude = tempLon;
		myObj.way[0].img = tempImg;
		myObj.way[0].getPic = tempgetPic;
		saveWay();
}

function saveWay() {
   //this will do a POST to the server and then redraw all the nodes.
	recalibrate();
	var key = document.getElementById('routeKey').value;
	var coverPic = myObj.way[0].img;
	var coverlat = myObj.way[0].latitude;
	var coverlon = myObj.way[0].longitude;
	var body = "route_key=" + key + "&coverPic=" + coverPic + "&coverLat=" + coverlat + "&coverLon="+coverlon+ "&way=" + JSON.stringify(myObj);
 	// clear out the old stuff
	waynode = document.getElementById("wayNodes")
	waynode.parentNode.removeChild(waynode);
	myObj.way = [];
	var req = createXMLHttpRequest();
 	req.open('POST', '/xhrsave', true);
	req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	req.setRequestHeader("Content-length", body.length);
	req.setRequestHeader("Connection", "close");
        req.onreadystatechange = onAddSuccess;
        req.send(body);

    // Callback for after a successful doAdd
    function onAddSuccess(response) {
     	if (req.readyState != 4) {return; }
	var serverResponse = req.responseText;
	//alert("server says: " + serverResponse);
    	var mg = document.createElement('div');
	mg.setAttribute('id', 'wayNodes' );
	mg.innerHTML = serverResponse;
	dadNode = document.getElementById("leftImages");
	dadNode.appendChild(mg);
        saved = true;
	window.location.reload();
    }	
}// end saveway


function mysortfn(a,b) {
	//enables sorting of the myObj multidimmensional array on the POSITION key/value, returns 0 if equal
	if ( parseFloat(a['position']) < parseFloat(b['position']) ) return -1;
	if (parseFloat(a['position']) > parseFloat(b['position']) ) return 1;
	return 0;
}

function reFill() {
	//first it sorts the memory array according to the position value. 
	//recalibrate will adjust the fractional values to whole integers
 	//the html dom nodes are zero based.  This displays the new sorted array on the screen
	//must be done when the nodes have been reordered, a new one added, or one deleted.
	//onchange="wayReorder( {{ forloop.counter0 }} , this.value)"
	myObj.way.sort(mysortfn);
	recalibrate();
	temp = '';
	var obLen = myObj.way.length ;
	//for (z=0; z < obLen; z++) {
	//	temp = temp + myObj.way[z].position + ', ';
	//}
	//alert('after recalibrate, positions are: ' + temp);
 	//the dom nodes are zero based.  This displays the new sorted array
	for (j=0; j < obLen; j++) {
		var x=document.getElementById(j + "_nodeform");
  		x.elements['position'].value = myObj.way[j].position;
  		x.elements['latitude'].value = myObj.way[j].latitude;
  		x.elements['longitude'].value = myObj.way[j].longitude;
  		x.elements['heading'].value = myObj.way[j].heading;
  		x.elements['zoom'].value = myObj.way[j].zoom;
  		x.elements['description'].value = myObj.way[j].description;
  		x.elements['image'].value = myObj.way[j].img;
		var y = document.getElementById(j + "_nodeImg");
		y.src = myObj.way[j].img + "?imgmax=512";
	}
        //alert("done with refill");
}

function wayReorder(oldPosition, newPosition) {
	//onchange="wayReorder( {{ forloop.counter0 }} , this.value)"
	//this.value is the value in the position widget box as just entered by user
	//first adjust the position of the FROM node to put it in front of the TO node (which is the value typed in the widget)
	//but reduce the TO value by 1/2 a point to put it in front of the node already there.  Then, sort the array object that is in memory.
	// finally use the ajax save to recalibrate and redraw the nodes.
	
	newPos = newPosition - 0.50
	//alert(" newpos is "+ newPos);
	myObj.way[oldPosition].position = newPos;
	//sort the memory array by position order
        //myObj.way.sort(mysortfn);
	//recalibratethe positions as integers and redraw the html nodes
	reFill();
	window.saved = false;
	//show the save button so the nodes can be edited
	readyEditorButtons();
}


function strip_tags(str, allowed_tags) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Luke Godfrey
    // +      input by: Pul
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Onno Marsman
    // *     example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i>,<b>');
    // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
    // *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
    // *     returns 2: '<p>Kevin van Zonneveld</p>'
    // *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
    // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
 
    var key = '', tag = '', allowed = false;
    var matches = allowed_array = [];
    var allowed_keys = {};
 
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
 
    // Build allowes tags associative array
    if (allowed_tags) {
        allowed_tags  = allowed_tags.replace(/[^a-zA-Z,]+/g, '');;
        allowed_array = allowed_tags.split(',');
    }
 
    str += '';
 
    // Match tags
    matches = str.match(/(<\/?[^>]+>)/gi);
 
    // Go through all HTML tags
    for (key in matches) {
        if (isNaN(key)) {
            // IE7 Hack
            continue;
        }
 
        // Save HTML tag
        html = matches[key].toString();
 
        // Is tag not in allowed list? Remove from str!
        allowed = false;
 
        // Go through all allowed tags
        for (k in allowed_array) {
            // Init
            allowed_tag = allowed_array[k];
            i = -1;
 
            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
            if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}
 
            // Determine
            if (i == 0) {
                allowed = true;
                break;
            }
        }
 
        if (!allowed) {
            str = replacer(html, "", str); // Custom replace. No regexing
        }
    }
 
    return str;
}

function wayUpdate(nodePost, formName, frmStr) {
	//EXAMPLE assignment: myObj.way[index].latitude = value
	saved = false;
	//show the save button so the nodes can be edited
	//document.getElementById("btnSave").style.visibility ="visible";
	//hide json buttons because the two are mutually exlusive
	//document.getElementById("btnshowJSON").style.visibility ="hidden";
        formValue = strip_tags(frmStr, '<b>, <i>, <a>, <img>');
	//alert("wayUpdate changing " + formName + ", value is " + frmStr);
	saved = false;
	switch (formName ) { 
		case 'position' :
			break;

		case 'heading' :
			myObj.way[nodePost ].heading = formValue;
			break;

		case 'image' :
			myObj.way[nodePost ].img = formValue;
			break;
			
		case 'latitude':
			myObj.way[nodePost ].latitude = formValue;
			break;

		case 'zoom':
		 	myObj.way[nodePost ].zoom = formValue;
			break;

		case 'longitude':
		 	myObj.way[nodePost ].longitude = formValue;
			break;

		case 'location':
		 	myObj.way[nodePost ].location = formValue;
			break;

		case 'description':
			myObj.way[nodePost ].description = formValue;
			break;
		default:
			alert("default case");
			break;
	}
}

function addNewWay(newPost, imgLink) {
	//does not save or redraw the nodes, just inserts a blank node at the end of the nodes, 
	//typically for use in bending the route polygons
	var size = myObj.way.length;
	var lastUsed = size - 1;
	if ( !imgLink ) { imgLink = ''; };
        //parentNode = document.getElementById(newPost + "_nodepad");
	var newPos = parseFloat(newPost) + 0.1;
	//alert("adding node: " + myObj.way.length);
	myObj.way[size] = {"description":"", "img":imgLink, "getPic":"", "zoom":"",  "longitude":"", "latitude":"", "position": newPos, "heading": ""};
	//myObj.way.sort(mysortfn);
	//waynode.parentNode.removeChild(waynode);	
	// the following string is just the html needed to display a blank/new node.
var nodeString = '<div id = "' + size + '_nodepad" onclick="editWay( ' + size + '); return false;" onmouseover="pointWay(' + size + ' ); return false;" onmouseout="whiteWay( ' + size + ' ); return false;" class="imgdata"><form action="#" id="' + size + '_nodeform" name="' + size + '_nodeform" >	<p class="banner" ><button type="button" style="float:right" class="nav" onclick="deleteWay(' + size + ')" > Delete </button>POSITION: <input class="invisiForm" type="input" onchange="wayReorder( ' + size + ' , this.value)" id="position" name="position" size=2 value="' + size + ' "/> (Edit number to change position)</p><ul><li>LATITUDE: <em>*</em> &nbsp;  &nbsp; &nbsp;<input class="invisiForm" type = "input" onchange="wayUpdate( ' + size + ', this.name, this.value )" name="latitude" value=" "/> <li>LONGITUDE: <em>*</em>  &nbsp;  <input class="invisiForm"  type = "input" onchange="wayUpdate(' + size + ', this.name, this.value )" name="longitude" value=" "/> <li>HEADING:  &nbsp;  &nbsp;  &nbsp;  &nbsp;<input class="invisiForm"  type = "input" onchange="wayUpdate(' + size + ', this.name, this.value )" name="heading" value=" "/><li>	ZOOM:  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; <input class="invisiForm" type="input" onchange="wayUpdate( ' + size + ', this.name, this.value )" name="zoom" value=""/><li> DESCRIPTION: &nbsp;  <textarea class="invisiForm"  type = "input" onchange="wayUpdate( ' + size + ', this.name, this.value )" name="description" /> </textarea>IMAGE:  &nbsp;  &nbsp<input class="invisiForm"  type = "input" onchange="wayUpdate(' + size + ', this.name, this.value )" name="image" value=" "/> <li></ul></form><img name="' + size + '_nodeImg"   id="' + size + '_nodeImg"  src="'+ imgLink +'?imgmax=512"  alt=""  /></div> </div> <button type="button" class="nav" onclick="addNewWay(' + size + ')" id="' + size + '_btnadd" name="' + size + '_btnadd">Insert New Node  </button>';
	


    	var mg = document.createElement('div');
	mg.innerHTML = nodeString;
	var lastNode = document.getElementById(lastUsed + "_btnadd")
	lastNode.parentNode.insertBefore(mg,lastNode.nextSibling);
	//lastNode.parentNode.removeChild(lastNode);
	//put the DOM nodes in order based on the position value
	reFill();
	window.saved = false;
	//show the save button so the nodes can be edited
	readyEditorButtons();
	editWay(newPost + 1 );
}

function getPicasaHandle() {
	//gets the user handle and returns all the public albums
	var newHandle = document.getElementById('tbxHandlename').value;
	if (newHandle == '' ) {
		alert("enter a valid Picasa user from google.picasa.com ");
		return;
	} else {
		var req = createXMLHttpRequest();
 		req.open('GET', '/rpcGetAlbum?handlename='+ newHandle, true);
       	 	req.onreadystatechange = onAddSuccess;
        	req.send(null);
	}

    // Callback for after a successful doAdd
    // server sends back a feed with all the public albums merged with album.html
    function onAddSuccess(response) {
	//alert("in callback: " + req.readyState);
     	if (req.readyState != 4) {return; }
      	var serverResponse = req.responseText;
   	if ( serverResponse == 'unknown username'){
		
		dadNode = document.getElementById("tbxHandlename");
		dadNode.value = serverResponse + '-' + dadNode.value;
		return;
	} else {
    		var mg = document.getElementById('editBox');
		mg.style.visibility ="visible";
		mg.innerHTML = serverResponse;
	}
	hideEditorButtons();
	document.getElementById('modeID').innerHTML = "Choose Picasa Album";
	var buildstring = '<div id="albumNote"><button type="button" id="btnAlbum" name="btnAlbum"class="nav" onclick="getPicasaPics(this.value)" value='+ newHandle + '  style="visibility:visible"> View Pictures </button>';
	buildstring = buildstring  + btns.strCancelMode + '</div>';
	document.getElementById('btnHolder').innerHTML = buildstring;
	document.getElementById('helpNode').innerHTML = '<img src="/static/icons/help.gif" height=17 width=17 > These are the public albums available.  Check the album to be opened. Then press the View Pictures button</p>';
	
   }
}

function getPictureLink() {
	var newLink= document.getElementById('tbxLinkname').value;
	if (newLink == '' ) {
		alert("enter picture's internet address. Example:  http://b.ads2.msn.com/CIS/66/000/000/000/001/832.jpg ");
		return;
	} else {

    		var mg = document.getElementById('editBox');
		mg.style.visibility ="visible";
		mg.innerHTML = "<img src='" + newLink + "'>";
	}
	hideEditorButtons();
	document.getElementById('modeID').innerHTML = "Adding to Picture List";
	var buildstring = '<button type="button" id="btnAlbum" name="btnAlbum"class="nav" onclick="addNewWay(1, this.value)" value='+ newLink + '  style="visibility:visible"> Add this picture </button>';
	buildstring = buildstring  + btns.strCancelMode ;
	document.getElementById('btnHolder').innerHTML = buildstring;
	document.getElementById('helpNode').innerHTML = '<img src="/static/icons/help.gif" height=17 width=17 > Add this picture to the Picture list?</p>';
	
}

function getPicasaPics(newHandle) {
        //user has selected an album by clicking a toggle button, show the pictures in it
	//look through all the radio buttons to find which one is checked:
	btns.strCancelMode = '<button type="button" id="btnCancelMode" name="btnCancelMode" class="nav" onClick="readyEditorButtons()"> Cancel </button>';
	
	for (var i=0; i < document.albumForm.rdo_albumname.length; i++)
   	{
   		if (document.albumForm.rdo_albumname[i].checked)
     		 {
      			var newAlbum = document.albumForm.rdo_albumname[i].value;
     		 }
	}
        tg = document.getElementById("albumNote");
        tg.innerHTML= "<blink> ...  loading ... </blink> " + newAlbum;

	if (typeof(newAlbum) == "undefined" ) {
		tg.innerHTML = 'check one of the albums listed below';
		var buildstring = '<div id="albumNote"><button type="button" id="btnAlbum" name="btnAlbum"class="nav" onclick="getPicasaPics(this.value)" value='+ newHandle + '  style="visibility:visible"> View Pictures </button>';

		buildString = buildString  + btns.strCancelMode + '</div>';
		document.getElementById('btnHolder').innerHTML = buildstring;
		return;
	}
	var req = createXMLHttpRequest();
 	req.open('GET', '/rpcGetPics?handlename='+ newHandle + "&albumname=" + newAlbum, true);
        req.onreadystatechange = onAddSuccess;
        req.send(null);

    // Callback for after a successful doAdd
    // server sends listof pictures merged with picpics.html
    function onAddSuccess(response) {
        document.getElementById("albumNote").innerHTML = '';
	//alert("in callback: " + req.readyState);
     	if (req.readyState != 4) {return; };
      	var serverResponse = req.responseText;
        var buildstring = '<input type="checkbox" id="allcbx" value="CHECK ALL PICTURES" onclick="checkAll()">Select ALL pictures<br><input type="button" name="button2" id="button2" value="Add" onclick="javascript:savePics();">Add the Checked Images to the Route';
	buildString = buildstring  + btns.strCancelMode ;
	document.getElementById("btnHolder").innerHTML = buildstring;
	document.getElementById('modeID').innerHTML = "<h2>Choose Pictures from Picasa Album </h2>";
        var eb = document.getElementById('editBox');
        eb.innerHTML ='<p> NOTE:   Click the Checkbox to select the pictures to include in the route. Information from the feed such as the the latitude and longitude values will be saved.  If these are missing they will need to be manually added.  The description will be included as the picture caption (all of these values can be edited later). Press the Add button. </p><hr>Scroll down to see all images.';
	var mg = document.createElement('div');
        mg.setAttribute('id', 'picasaPics');
	mg.innerHTML = serverResponse;
	eb.parentNode.insertBefore(mg, eb.nextSibling);
   }
}


function checkAll() {
	//alert("incheckall");
        if (!document.forms['picList'])
		return;
	var objCBX = document.forms['picList'].elements['cbx'];
	if (!objCBX)
		return;
	var countCBXs = objCBX.length;
	if (!countCBXs)
		objCBX.checked = true;
	else
		for (i=0; i<countCBXs; i++) {
		objCBX[i].checked = true;
	}
}

function savePics() { 
	//the submit button on the picture list triggers this function
	//build a list from form picList of the picassa feed values in the value attribute
	//this will do an ajax post to the server and make nodes for all pictures
	//alert("in savepics");
	
      	var pylist = [];
      	for (i=0; i<document.picList.cbx.length; i++) {
           
               if (document.picList.cbx[i].checked) {
                  pylist.push( document.picList.cbx[i].value );
               }
      	}
	
	var getstr = JSON.stringify(pylist);
	//alert('getstr is ' + getstr);
	var key = document.getElementById('routeKey').value;
	var body = "route_key=" + key + "&cbx=" + getstr;
	var req = createXMLHttpRequest();
 	req.open('POST', '/rpcSavePics', true);
	req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	req.setRequestHeader("Content-length", body.length);
	req.setRequestHeader("Connection", "close");
	//alert("req open and close");
        req.onreadystatechange = onAddSuccess;
        req.send(body);


    // Callback for after a successful doAdd
    //the response should include the new ways object
    //the route editor javascript does not need myobj to run, the viewer does
    function onAddSuccess(response) {
	//alert("in callback: " + req.readyState);
     	if (req.readyState != 4) {return; }
	var serverResponse = req.responseText;
	//alert(serverResponse);
	var eb=document.getElementById("editBox");
	eb.innerHTML = "";
	var mg=document.getElementById("wayNodes");
	mg.innerHTML = "";
	mg.innerHTML= serverResponse;
	window.location.reload();
	//saved = true;
	//document.getElementById("wayNodes").style.visibility ="visible";
	//document.getElementById("helpPicassa").style.visibility ="hidden";
	//document.getElementById("btnSave").style.visibility ="hidden";
    }	
}

function saveGPXpics() { 
	//the submit button on the picture list triggers this function
	//build a list from form picList of the picassa feed values in the value attribute
	//this will do an ajax post to the server and make nodes for all pictures
	
      	var pylist = [];
      	for (i=0; i<document.picList.cbx.length; i++) {
           
               if (document.picList.cbx[i].checked) {
                  //"{ picsrc:'', pos:'35.7729492 -82.995903', description:'Brown Gap. 3 gravel roads converged', typeLink:'', getPic:''}"
		  var tempstr = document.picList.cbx[i].value ;
		  //alert("in saveGPX the string is " + tempstr);
		  //fixtags;
                  pylist.push(tempstr );
               }
      	}
	var getstr = JSON.stringify(pylist);
	//alert('getstr is ' + getstr);
	var key = document.getElementById('routeKey').value;
	var body = "route_key=" + key + "&cbx=" + getstr ;
	var req = createXMLHttpRequest();
 	req.open('POST', '/rpcSavePics', true);
	req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	req.setRequestHeader("Content-length", body.length);
	req.setRequestHeader("Connection", "close");
	//alert("req open and close");
        req.onreadystatechange = onAddSuccess;
        req.send(body);


    // Callback for after a successful doAdd
    //the response should include the new ways object
    //the route editor javascript does not need myobj to run, the viewer does
    function onAddSuccess(response) {
	//alert("in callback: " + req.readyState);
     	if (req.readyState != 4) {return; }
	var serverResponse = req.responseText;
	//alert("this came back: " + serverResponse);
	var eb=document.getElementById("editBox");
	eb.innerHTML = "";
	var mg=document.getElementById("wayNodes");
	mg.innerHTML = "";
	mg.innerHTML= serverResponse;
	//alert("after server call, length is " + myObj.way.length);
	window.location.reload();
	//alert("after reload, length is " + myObj.way.length);
	//sortWaypoints();
	//saved = true;
	//document.getElementById("wayNodes").style.visibility ="visible";
	//document.getElementById("helpPicassa").style.visibility ="hidden";
	//document.getElementById("btnSave").style.visibility ="hidden";
    }	
}


function startPicasa() {
	//sets up the editor for picasa album retrieval
	if ( saved != true ) {
		if (confirm("Do you want to save your current edits? ")) {
			alert('confirmed');
			saveWay();
		}
	}	
document.getElementById("modeID").innerHTML = "Get Pictures from Picasa Web Albums ";
btns.strHandle = 'Enter Picasa User Name: ';
btns.strInputHandlename = '<input type = "text" id="tbxHandlename" name="tbxHandlename" style="visibility:visible"> <button type="button" id="btnHandle" name="btnHandle" class="nav" onclick="getPicasaHandle()" style="visibility:visible"> Submit </button>';

	hideEditorButtons();

	var strB =  btns.strHandle +   btns.strInputHandlename + btns.strCancelMode ;
     
	document.getElementById('btnHolder').innerHTML = strB;
	document.getElementById('helpNode').innerHTML = '<img src="/static/icons/help.gif"   height=17 width=17 >Type in the name of a Picasa User, from picasa.google.com.  For example, rambletown.'


}

function startManualPics() {
	//sets up the editor for picasa album retrieval
	if ( saved != true ) {
		if (confirm("Do you want to save your current edits? ")) {
			alert('confirmed');
			saveWay();
		}
	}	
document.getElementById("modeID").innerHTML = "Load Pictures from Links ";
btns.strHandle = "Enter URL Link to web picture: ";
btns.strInputHandleName = ' <input type = "text" id="tbxLinkname" name="tbxLinkname" style="visibility:visible"><button type="button" id="btnLink" name="btnLink"class="nav" onclick="getPictureLink()" style="visibility:visible"> Submit </button>';

	hideEditorButtons();

	var strB =  btns.strHandle +   btns.strInputHandleName + btns.strCancelMode ;
     
	document.getElementById('btnHolder').innerHTML = strB;
	document.getElementById('helpNode').innerHTML = '<img src="/static/icons/help.gif"   height=17 width=17 >Type in the link to a web picture.'
}

function startGPXpics() {
	// searches through gpx data for image links
	if ( saved != true ) {
		if (confirm("Do you want to save your current edits? ")) {
			alert('confirmed');
			saveWay();
		}
	}
	if ( GPXdata.GPXexists == true ) {
		var key = document.getElementById('routeKey').value;
		var body = "route_key=" + key;
		var req = createXMLHttpRequest();
 		req.open('POST', '/rpcGetPicsGPX', true);
        	req.onreadystatechange = onGPXSuccess;
		req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		req.setRequestHeader("Content-length", body.length);
		req.setRequestHeader("Connection", "close");
        	req.send(body);
	} else {
		document.getElementById('helpNode').innerHTML = "No gpx file data has been added for this route."
	} 


	function onGPXSuccess(response) {
        	//alert("in callback: " + req.readyState);
     		if (req.readyState != 4) {return; };
      		var serverResponse = req.responseText;
        	var buildstring = '<input type="checkbox" id="allcbx" value="CHECK ALL PICTURES" onclick="checkAll()">Select ALL <br><input type="button" name="button2" id="button2" value="Add" onclick="javascript:saveGPXpics();">Add the Checked Images to the Route';
		buildString = buildstring  + btns.strCancelMode ;
		document.getElementById("btnHolder").innerHTML = buildstring;
		document.getElementById('modeID').innerHTML = "<h2>Choose Pictures from GPX Waypoints: </h2>";
        	var eb = document.getElementById('editBox');
        	eb.innerHTML ='<p> NOTE:   Click the Checkbox to select the pictures to include in the route. Information from the feed such as the the latitude and longitude values will be saved.  If these are missing they will need to be manually added later.  The description will be included as the picture caption (all of these values can be edited later). Press the Add button. </p><hr>Scroll down to see all images.';
		var mg = document.createElement('div');
        	mg.setAttribute('id', 'gpxPics');
		mg.innerHTML = serverResponse;
		eb.parentNode.insertBefore(mg, eb.nextSibling);
   }
}

function updateJSON() {
	//The page needs to be reloaded to get a fresh memory object, myObj
	//	window.location.reload();
}

function editWay(post) {
	// when a node is clicked on it is seclected.  Each node has it's own form.  When selected, the form's components/widgets are outlined 
	// with visible borders.  
	// only one form can be selected at a time because all others are turned off.
	// The globalNode value designates which node is selected
        if ( globalNode != post ) {
		//change previously selected div back to starting color and borders
		document.getElementById(globalNode + "_nodepad").style.backgroundColor = "white";
		var x=document.getElementById(globalNode + "_nodeform");
		//this loop hides the form borders 
		for (var i=0; i<x.length; i++) {
  			 x.elements[i].style.border="none";
  		}
		
		//finally the selected node is colored and form components are outlined
		//note this will stay in effect until another node is clicked
		document.getElementById(post + "_nodepad").style.backgroundColor = "blue";
		var x=document.getElementById(post + "_nodeform");
		//show the form borders on the new div
		for (var i=0;i<x.length;i++) {
  			 x.elements[i].style.border="solid";
  		}
	}
	//finally, update the globalNode to be the new selection
	globalNode = post;
}

function whiteWay(post) {
	//after the mouse leaves a highlited node it returns back to white
	if ( post != globalNode ) {
		ego = post + "_nodepad";
		document.getElementById(ego).style.backgroundColor = "white";
	}
}

function pointWay(post) {
 	//when the mouse is over a node it is  highlighted, map is centered on the geocode
	var count;
	var ego = ""; 
	if (post != globalNode) {
		ego = post + "_nodepad";
		document.getElementById(ego).style.backgroundColor = "yellow";
    	}
	glat = myObj.way[post].latitude;
	glong = myObj.way[post].longitude;
	gzoom = myObj.way[post].zoom;
  
	if ( glat != '') {
		map.removeOverlay(gmarkers[0]);
		var gPT = new GLatLng(glat,glong);
		map.panTo(gPT); 
		var marker = new GMarker(gPT);
  		map.addOverlay(marker);
		gmarkers[0] = marker ;

	}    
}


function deleteWay(np ) {
 	//copies all array contents up a notch and then pops off the last one, saves memory object and reload page 
	//starting at the one to be replaced, shift each of the following members up a position
//,{"description":"","img":"","zoom":"17","longitude":"-75.97158014774323","getPic":"","latitude":"36.83134890802761","position":2,"heading":""}
		var nodePost = parseInt(np);
		var obLen = myObj.way.length -1 ;
		for  ( i = nodePost; i < obLen; i++ ) {
		
			myObj.way[i].description = myObj.way[i+1].description;
			myObj.way[i].img	 = myObj.way[i+1].img ;
			myObj.way[i].getPic	 = myObj.way[i+1].getPic ;
			myObj.way[i].zoom 	 = myObj.way[i+1].zoom;
			myObj.way[i].longitude   = myObj.way[i+1].longitude;
			myObj.way[i].latitude 	 = myObj.way[i+1].latitude ;
			myObj.way[i].position 	 = myObj.way[i+1].position;
			myObj.way[i].heading 	 = myObj.way[i+1].heading;
		}

  		
		//in javascript, only way to delete an array member is to pop it off the bottom
		//pop() will automatically resize the array length
		myObj.way.pop();
		
		reFill();
                //need to remove the last node which is no longer holding data
                var orphan = obLen;
		//alert("orphan is " + orphan);
		waynode = document.getElementById(orphan + "_nodepad");
		waynode.parentNode.removeChild(waynode);
		var lastNode = document.getElementById(orphan + "_btnadd");
		lastNode.parentNode.removeChild(lastNode);

		
		saved = false;
		readyEditorButtons();
}

function readyEditorButtons() {
	//configuration for editor in starting position. displays the save button if the picture list has outstanding changes
	document.getElementById('modeID').innerHTML = 'Editing Options: ';
	 var strB = 'x';

	//alert("saved is " + window.saved);
	strB = btns.strGetPicsPCA +  btns.strGetPicsGPX + btns.strGetPicsMAN +  btns.strbtnshowJSON + btns.strbtnshowGPX ;

	if ( window.saved != true ) {
		strB = strB + btns.strbtnSave;
	}
       
	document.getElementById('btnHolder').innerHTML = strB;
	document.getElementById('editBox').innerHTML = "";
}

function hideEditorButtons() {
	//Prepare editor. Hide all buttons and form widgets used in editor area, all way nodes in the leftImages div
	//this is for going into the JSON or GPX editor
	document.getElementById('btnHolder').innerHTML = '';
}

function uploadGPXfile() {
	//run the action="addGPX/" or server function routeDetailsGPX()
	//submits form with "input type = file" to upload the users gpx file
	document.forms['upform'].submit();
}

function saveGPX() {
	//run the action="addGPX/" or server function routeDetailsGPX()
	//submits form with "input type = file" to upload the users gpx file
	document.forms['frmGPXData'].submit();
}

function saveJSON() {
	//submit the JSONform
	//alert("in saveJSON");
	document.forms['frmRouteData'].submit();
}


function showJSON() {
	//writes the memory object into the JSON box, does not save anything, changes button visibility
	//to avoid confusing the user, the save route and save JSON buttons are never visible at the same time
	if ( saved != true ) {
		if (confirm("Do you want to save the latest changes? (Cancel to discard changes)"))  saveway();
	}
	
btns.strupdateJSON = '<input type="submit" id="updateJSON" name="updateJSON" style="visibility:visible" class="nav" onClick="saveJSON()" value="Save changes to JSON" >';
btns.strbtnhideJSON = '<button type="button" id="btnhideJSON" name="btnhideJSON" class="nav" onClick="hideJSON()" style="visibility:visible" > Cancel </button>';

	hideEditorButtons();
	document.getElementById("formHolder").style.display = "inline";
	document.getElementById("JSONbox").style.visibility = "visible";
	// make the text area bigger
		var x=document.getElementById("frmRouteData");
  		x.elements['JSONbox'].style.height="100px";

	var strB =  btns.strupdateJSON +   btns.strbtnhideJSON  ;
     
	document.getElementById('btnHolder').innerHTML = strB;
	document.getElementById('modeID').innerHTML = 'Editing JSON ';

        //this function writes the current object as it is in memory to the json box
	myObj2string();
}

function hideJSON() {
	//cancels operation, does not save anything, changes button visibility

	hideEditorButtons();

		var x=document.getElementById("frmRouteData");
  		x.elements['JSONbox'].style.height="12px";
	document.getElementById("JSONbox").style.visibility = "hidden";
	document.getElementById("formHolder").style.display = "none";
	readyEditorButtons();

}

function showGPX() {
	//to avoid confusing the user, the save route and save JSON and GPX buttons are never visible at the same time

	if ( saved != true ) {
		if (confirm("Do you want to save the latest changes? (Cancel to discard changes)"))  saveway();
	}

btns.strupdateGPX = '<button type="button" id="updateGPX" name="updateGPX" style="visibility:visible" class="nav" onClick="saveGPX()">Save changes to GPX </button>';
btns.strbtnhideGPX = '<button type="button" id="btnhideGPX" name="btnhideGPX" class="nav" style="visibility:visible" onClick="hideGPX()" > Cancel </button>';

btns.formGPX = '<form method="post" name="upform" id="upform" action="loadGPX/" enctype="multipart/form-data"> ';
btns.inputGPX = '<br> Browse for a file: <input type="file" name="subGPX" id="subGPX"> <input type="button" id="btnUploadGPX" name="btnUploadGPX" onclick="uploadGPXfile();" class="nav" value="Display " > </form>';

	hideEditorButtons();
	document.getElementById("formHolder").style.display = "inline";
	document.getElementById("GPXbox").style.visibility = "visible";
	// make the text area bigger
		var x=document.getElementById("frmGPXData");
  		x.elements['GPXbox'].style.height="100px";

	var strB =  btns.strupdateGPX +   btns.strbtnhideGPX  + btns.formGPX + btns.hiddenKey + btns.inputGPX;
     	document.getElementById('modeID').innerHTML = 'Editing GPX';
	document.getElementById('btnHolder').innerHTML = strB;
}
//document.forms['frmGPXData'].submit();

function hideGPX() {
	//cancels operation, does not save anything, changes button visibility
	hideEditorButtons();
		var x=document.getElementById("frmGPXData");
  		x.elements['GPXbox'].style.height="12px";
	document.getElementById("GPXbox").style.visibility = "hidden";
	document.getElementById("formHolder").style.display = "none";
	readyEditorButtons();
}


function showHelp(content) {
	
	var lastNode = document.getElementById('helpNode');
	lastNode.innerHTML = content;
    }

function helpNode(str) {
	//helpNode(this.name) name of button
	//alert("this helpNode " + str);
	var hn = document.getElementById('helpNode');
 	switch (str) {
	case ('btnGetPicsPCA') : 
		hn.innerHTML = 'Select pictures from an on-line Picasa Web Album';
		break;
	case ('btnGetPicsMAN') : 
		hn.innerHTML = 'Browse for single pictures on internet';
		break;
	case ('btnGetPicsGPX') : 
		hn.innerHTML = 'If a GPX file has been added to this route, search it for pictures';
		break;
	case ('btnshowJSON') : 
		hn.innerHTML = 'Display and/or edit the internal JSON for this route (automatically created by the picture list)';
		break; 
	case ('btnshowGPX') : 
		hn.innerHTML = 'Enter a GPX file for this route (optional)';
		break;
	default:
		hn.innerHTML = "<br>";
	} //end switch
	
}

function hideHelp() {
	
	var lastNode = document.getElementById('helpNode')
	lastNode.innerHTML = "";
    }
function unload() {
	
 	if ( saved != true ) {
		if (confirm("Do you want to save changes before leaving this page? (cancel to discard) "))  saveWay();
	}
	globalNode = 0;
	map.Dispose();
	GUnload()
	globalNode = 0;
	saved = true;
	playing = false;
	numPosts = 0 ;
	myObj = none ; 
	myGPX = none;
	parkingArray = '';
	restroomsArray = '';
	//var head = document.getElementsByTagName('head').item(0);
  	//var js = document.getElementById(scriptName);
  	//js.parentNode.removeChild(js);
}

    
    //]]>

